using System;
using System.Collections.Generic;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestDMUniqueConstraintPropertySelectorControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }


        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();

        }

        [Test]
        public void Test_NullControlFactory_RaisesError()
        {
            //--------------- Set up test pack ------------------         
            //--------------- Test Preconditions ----------------
            //--------------- Execute Test ----------------------
            try
            {
                new DMUniqueConstraintPropertySelectorControl(null);
                Assert.Fail("expected Err");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("controlFactory", ex.ParamName);
                StringAssert.Contains("Value cannot be null", ex.Message);
            }
        }

        [Test]
        public void Test_Construction()
        {
            //--------------- Set up test pack ------------------
            
            //--------------- Test Preconditions ----------------

            //--------------- Execute Test ----------------------
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(GlobalUIRegistry.ControlFactory);
            //--------------- Test Result -----------------------
            Assert.AreEqual(2, control.Controls.Count);
            Assert.IsInstanceOf(typeof(IMultiSelector<DMProperty>), control.Controls[0]);
            Assert.IsInstanceOf(typeof(IButtonGroupControl), control.Controls[1]);
            IButtonGroupControl buttonGroupControl = (IButtonGroupControl) control.Controls[1];
            Assert.IsNotNull(buttonGroupControl["Save"]);
            Assert.IsNotNull(buttonGroupControl["Cancel"]);
            Assert.IsNotNull(buttonGroupControl["Close"]);

        }


    
        [Test]
        public void Test_SetUniqueConstraint_NoParentClass_DoesNotRaiseError()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = new DMUniqueConstraint();
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            //--------------- Test Preconditions ----------------

            //--------------- Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Result -----------------------
            Assert.AreSame(uniqueConstraint, control.UniqueConstraint);
        }

        [Test]
        public void Test_SetUniqueConstraint()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = new DMUniqueConstraint();
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            //--------------- Test Preconditions ----------------

            //--------------- Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Result -----------------------
            Assert.AreSame(uniqueConstraint, control.UniqueConstraint);
        }

        [Test]
        public void Test_SetUniqueConstraintWithTwoProps()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMUniqueConstraint uniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();

            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(GlobalUIRegistry.ControlFactory);
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(2, dmClass.Properties.Count);
            Assert.AreEqual(0, uniqueConstraint.Properties.Count);
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Result -----------------------
            IMultiSelector<DMProperty> multiSelector = control.MultiSelector;
            Assert.IsNotNull(multiSelector);
            Assert.AreEqual(dmClass.Properties.Count, multiSelector.AvailableOptionsListBox.Items.Count);
            Assert.AreEqual(0, multiSelector.SelectedOptionsListBox.Items.Count);
        }



        [Test]
        public void Test_SetUniqueConstraint_HasProperties()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMProperty dmProperty = TestUtilsShared.CreateUnsavedValidDMProperty(dmClass);
            DMUniqueConstraint uniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            uniqueConstraint.AddPropertyInfo(dmProperty);
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(GlobalUIRegistry.ControlFactory);
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(3, dmClass.Properties.Count);
            Assert.AreEqual(1, uniqueConstraint.Properties.Count);
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Result -----------------------
            IMultiSelector<DMProperty> multiSelector = control.MultiSelector;
            Assert.IsNotNull(multiSelector);
            Assert.AreEqual(2, multiSelector.AvailableOptionsListBox.Items.Count);
            Assert.AreEqual(1, multiSelector.SelectedOptionsListBox.Items.Count);
        }

        [Test]
        public void Test_SetUniqueConstraintLoadsProperties()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            //--------------- Test Preconditions ----------------
            BusinessObjectCollection<DMProperty> properties = dmClass.Properties;
            Assert.AreEqual(2, properties.Count);
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            //--------------- Test Result -----------------------
            List<DMProperty> allOptions = new List<DMProperty>(control.MultiSelector.AllOptions);
            Assert.AreEqual(properties.Count, allOptions.Count);
            Assert.Contains(properties[0], allOptions);
            Assert.Contains(properties[1], allOptions);
            Assert.AreEqual(0, control.MultiSelector.SelectedOptions.Count);
        }

        [Test]
        public void Test_SetNullUniqueConstraint_DoesNotRaiseError()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            //--------------- Test Preconditions ----------------
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = null;
            //--------------- Test Result -----------------------
            Assert.AreEqual(0, control.MultiSelector.AllOptions.Count);
            Assert.AreEqual(0, control.MultiSelector.SelectedOptions.Count);
        }

        [Test]
        public void Test_SetUniqueContraint_ThenSetNullUniqueConstraint_ClearsOptions()
        {
            //--------------- Set up test pack ------------------
            DMClass dmClass = TestUtilsShared.CreateSavedDMClassWithProps();
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            control.UniqueConstraint = dmClass.UniqueConstraints.CreateBusinessObject();
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(dmClass.Properties.Count, control.MultiSelector.AllOptions.Count);
            Assert.AreEqual(0, control.MultiSelector.SelectedOptions.Count);
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = null;
            //--------------- Test Result -----------------------
            Assert.AreEqual(0, control.MultiSelector.AllOptions.Count);
            Assert.AreEqual(0, control.MultiSelector.SelectedOptions.Count);
        }

        [Test]
        public void Test_SetUniqueConstraintSetsSelectedOptions()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithProperties();
            DMClass dmClass = uniqueConstraint.Class;
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(2, uniqueConstraint.UniqueConstraintProperties.Count);
            Assert.AreEqual(3, dmClass.Properties.Count);
            //--------------- Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Result -----------------------
            Assert.AreEqual(3, control.MultiSelector.AllOptions.Count); 
            Assert.AreEqual(2, control.MultiSelector.SelectedOptions.Count);
            Assert.AreEqual(2, control.MultiSelector.SelectedOptionsListBox.Items.Count);
            Assert.AreEqual(1, control.MultiSelector.AvailableOptionsListBox.Items.Count);
        }

        [Test]
        public void Test_AddUniqueConstaintProperty_UpdatesUniqueConstraint()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithProperties();
            DMClass dmClass = uniqueConstraint.Class;
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            control.UniqueConstraint = uniqueConstraint;
            //--------------- Test Preconditions ----------------
            Assert.AreEqual(2, uniqueConstraint.UniqueConstraintProperties.Count);
            Assert.AreEqual(3, dmClass.Properties.Count);
            
            //--------------- Execute Test ----------------------
            control.MultiSelector.GetButton(MultiSelectorButton.SelectAll).PerformClick();

            //--------------- Test Result -----------------------
            Assert.AreEqual(3, uniqueConstraint.UniqueConstraintProperties.Count);
            Assert.IsTrue(uniqueConstraint.Status.IsDirty);
        }

        [Test]
        public void Test_RemoveUniqueConstaintProperty_UpdatesUniqueConstraint()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithProperties();
            DMClass dmClass = uniqueConstraint.Class;
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            control.UniqueConstraint = uniqueConstraint;

            //--------------- Test Preconditions ----------------
            Assert.AreEqual(2, uniqueConstraint.UniqueConstraintProperties.Count);
            Assert.AreEqual(3, dmClass.Properties.Count);
         
            //--------------- Execute Test ----------------------
            control.MultiSelector.GetButton(MultiSelectorButton.DeselectAll).PerformClick();
            //--------------- Test Result -----------------------
            Assert.AreEqual(0, uniqueConstraint.UniqueConstraintProperties.Count);
            Assert.IsTrue(uniqueConstraint.Status.IsDirty);
        }

        [Test]
        public void Test_AddDMPropertyUpdatesSelectorList()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithProperties();
            DMClass dmClass = uniqueConstraint.Class;
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            control.UniqueConstraint = uniqueConstraint;
            IMultiSelector<DMProperty> multiSelector = control.MultiSelector;

            //--------------- Test Preconditions ----------------
            Assert.AreEqual(3, multiSelector.AllOptions.Count); 
            Assert.AreEqual(2, multiSelector.SelectedOptions.Count);


            //--------------- Execute Test ----------------------
            DMProperty newProperty = dmClass.Properties.CreateBusinessObject();

            //--------------- Test Result -----------------------
            Assert.AreEqual(4, multiSelector.AllOptions.Count);
            Assert.AreEqual(2, multiSelector.SelectedOptions.Count);
            Assert.Contains(newProperty, new List<DMProperty>(multiSelector.AllOptions));
            Assert.AreEqual(2, control.MultiSelector.AvailableOptionsListBox.Items.Count);
            Assert.AreEqual(2, control.MultiSelector.SelectedOptionsListBox.Items.Count);
        }

        [Test]
        public void Test_RemoveDMPropertyUpdatesSelectorList()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraint uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithProperties();
            DMClass dmClass = uniqueConstraint.Class;
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            control.UniqueConstraint = uniqueConstraint;
            IMultiSelector<DMProperty> multiSelector = control.MultiSelector;

            //--------------- Test Preconditions ----------------
            Assert.AreEqual(4, multiSelector.AllOptions.Count); 
            Assert.AreEqual(2, multiSelector.SelectedOptions.Count);
            Assert.Contains(dmProperty, new List<DMProperty>(multiSelector.AllOptions));
            Assert.AreEqual(2, control.MultiSelector.AvailableOptionsListBox.Items.Count);
            Assert.AreEqual(2, control.MultiSelector.SelectedOptionsListBox.Items.Count);

            //--------------- Execute Test ----------------------
            dmClass.Properties.Remove(dmProperty);

            //--------------- Test Result -----------------------
            Assert.AreEqual(3, multiSelector.AllOptions.Count);
            Assert.AreEqual(2, multiSelector.SelectedOptions.Count);
            Assert.IsFalse(multiSelector.AllOptions.Contains(dmProperty));
            Assert.AreEqual(1, control.MultiSelector.AvailableOptionsListBox.Items.Count);
            Assert.AreEqual(2, control.MultiSelector.SelectedOptionsListBox.Items.Count);

        }

        [Test]
        public void Test_CloseButtonClick()
        {
            //--------------- Set up test pack ------------------
            DMUniqueConstraintPropertySelectorControl control = new DMUniqueConstraintPropertySelectorControl(new ControlFactoryWin());
            bool closeEventFired = false;
            control.CloseClicked += (sender, e) => closeEventFired = true;
            IButton closeButton = control.ButtonGroupControl["Close"];
            //--------------- Test Preconditions ----------------
            Assert.IsNotNull(closeButton);
            Assert.IsFalse(closeEventFired);
            //--------------- Execute Test ----------------------
            closeButton.PerformClick();
            //--------------- Test Result -----------------------
            Assert.IsTrue(closeEventFired);
        }

    }


}
